<template>
  <div ref="pull_scroller">
    <div class="pulldown-wrapper" v-show="isPullRefresh">
      <span class="pulldown">
        <img v-if="pulldownImg" :src="pulldownImg" class="pullImg"> {{refreshText}}
      </span>
    </div>
    <slot></slot>
    <div class="pullup-wrapper" v-show="isPullUpLoad">
      <span class="pullup">
        <img v-if="pullupImg" :src="pullupImg" class="pullImg"> {{loadText}}
      </span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'pull-refresh-list',
  data() {
    return {
      refreshText: '',
      loadText: '',
      isPullRefresh: false,
      isPullUpLoad: false,
      touchMove: false,
      pulldownImg: '',
      pullupImg: '',
      downArrow: require('@/assets/img/downArrow.png'),
      upArrow: require('@/assets/img/upArrow.png'),
      loadArrow: require('@/assets/img/loadArrow.png'),
      startY: 0,
      endY: 0
    }
  },
  methods: {
    // 判断是否支持触摸事件
    isTouchDevice() {
      try {
        document.createEvent('TouchEvent')
        // alert('支持TouchEvent事件！')

        this.bindEvent() // 绑定事件
      } catch (e) {
        console.log('不支持TouchEvent事件！' + e.message)
      }
    },
    // 绑定事件
    bindEvent() {
      this.$refs.pull_scroller.addEventListener('touchstart', this.touchSatrtFunc, false)
      this.$refs.pull_scroller.addEventListener('touchmove', this.touchMoveFunc, false)
      this.$refs.pull_scroller.addEventListener('touchend', this.touchEndFunc, false)
    },
    // touchstart事件
    touchSatrtFunc(evt) {
      // evt.preventDefault() // 阻止触摸时页面的缩放、滚动条滚动等
      const touch = evt.touches[0] // 获取第一个触点
      const y = Number(touch.pageY) // 页面触点Y坐标
      // 记录触点初始位置
      this.startY = y

      this.pulldownImg = this.downArrow
      this.pullupImg = this.upArrow
      this.refreshText = '下拉刷新'
      this.loadText = '上拉加载'
    },
    // touchmove事件，这个事件无法获取坐标
    touchMoveFunc(evt) {
      // evt.preventDefault() // 阻止触摸时页面的缩放、滚动条滚动等
      this.touchMove = true
      const touch = evt.touches[0] // 获取第一个触点
      const y = Number(touch.pageY) // 页面触点Y坐标
      const slideY = Math.abs(y - this.startY) // 上下滑动距离

      // 判断滑动方向
      if (y > this.startY) {
        // 往下滑
        this.isPullRefresh = true
        this.isPullUpLoad = false
        this.$refs.pull_scroller.style.transform =
            'translateY(' + slideY + 'px)'

        // 刷新临界点
        if (slideY > 110) {
          this.pulldownImg = this.upArrow
          this.refreshText = '释放立即刷新'
        } else {
          this.pulldownImg = this.downArrow
          this.refreshText = '下拉刷新'
        }
      } else {
        // 往上滑
        this.isPullRefresh = false
        this.isPullUpLoad = true
        this.$refs.pull_scroller.style.transform =
            'translateY(-' + slideY + 'px)'

        // 加载临界点
        if (slideY > 100) {
          this.pullupImg = this.downArrow
          this.loadText = '释放立即加载'
        } else {
          this.pullupImg = this.upArrow
          this.loadText = '上拉加载'
        }
      }

      // 记录触点结束位置
      this.endY = y
    },
    // touchend事件
    touchEndFunc() {
      // evt.preventDefault() // 阻止触摸时页面的缩放、滚动条滚动等
      const slideY = Math.abs(this.endY - this.startY) // 上下滑动距离
      if (!this.touchMove) {
        // 阻止点击触发滑动
        return
      }

      this.$refs.pull_scroller.style.transition = '.5s'
      // 判断滑动方向
      if (this.endY > this.startY) {
        // 往下滑
        // 刷新临界点
        if (slideY > 110) {
          this.$refs.pull_scroller.style.transform = 'translateY(60px)'
          this.pulldownImg = this.loadArrow
          this.refreshText = '正在刷新...'
          // 刷新
          this.$emit('pullScroller', 0)
          setTimeout(() => {
            this.pulldownImg = ''
            this.refreshText = '刷新成功'
            this.$refs.pull_scroller.style.transform = 'translateY(0)'
            setTimeout(() => {
              this.isPullRefresh = false
            }, 300)
          }, 500)
        } else {
          // 回弹还原
          this.$refs.pull_scroller.style.transform = 'translateY(0)'
          this.isPullRefresh = false
        }
      } else {
        // 往上滑
        // 加载临界点
        if (slideY > 100) {
          this.$refs.pull_scroller.style.transform = 'translateY(-60px)'
          this.pullupImg = this.loadArrow
          this.loadText = '加载中...'
          // 加载
          this.$emit('pullScroller', 1)
          setTimeout(() => {
            this.pullupImg = ''
            this.loadText = '加载成功'
            this.$refs.pull_scroller.style.transform = 'translateY(0)'
            setTimeout(() => {
              this.isPullUpLoad = false
            }, 300)
          }, 500)
        } else {
          // 回弹还原
          this.$refs.pull_scroller.style.transform = 'translateY(0)'
          this.isPullUpLoad = false
        }
      }
      this.touchMove = false
    }
  },
  mounted() {
    this.$refs.pull_scroller.style.minHeight = document.body.clientHeight - 110 + 'px'
    this.isTouchDevice()
  }
}
</script>

<style lang="less">
.pulldown-wrapper {
  position: absolute;
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  transform: translateY(-100%) translateZ(0);
  text-align: center;
  color: #999;
}
.pullup-wrapper {
  position: absolute;
  bottom: -2em;
  left: 0;
  width: 100%;
  overflow-x: hidden;
  box-sizing: border-box;
  padding: 20px;
  text-align: center;
  color: #999;
}
.pullImg {
  width: 1em;
  vertical-align: middle;
}
</style>
